package ru.ssau.hibernate.util;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;

import ru.ssau.university.persistence.entity.CommonEntity;

public abstract class AbstractDAO<T extends CommonEntity> {
	
	protected Class<T> objectClass;	
	
	public void updateInBase(T obj) {
		Session session = HibernateUtil.getSession();
		if (obj.getId() == null) {
			throw new IllegalStateException("Object doesn't have an id and therefore can not be updated");
		}
		session.beginTransaction();
		session.update(obj);
		session.getTransaction().commit();
	}
	
	public Long save(T obj) {
		Session session = HibernateUtil.getSession();
		if (obj.getId() != null) {
			throw new IllegalStateException("Object has an id and therefore already exists in db. Use updateInBase instead.");
		}
		session.beginTransaction();
		Long id = (Long) session.save(obj);
		session.getTransaction().commit();
		return id;
	}
	
	public T update(T obj) {
		return findById(obj.getId());
	}
	
	@SuppressWarnings("unchecked")
	public T findById(Long id) {
		Session session = HibernateUtil.getSession();
		return (T) session.load(objectClass, id);
	}
	
	public void delete(T obj) {
		Session session = HibernateUtil.getSession();
		session.getTransaction().begin();
		session.delete(obj);
		session.getTransaction().commit();
		session.flush();
		session.close();
	}
	
	protected Criteria createCriteria() {
		Session session = HibernateUtil.getSession();
		return session.createCriteria(objectClass);
	}
	
	protected Query createQuery(String query) {
		Session session = HibernateUtil.getSession();
		return session.createQuery(query);
	}
	
	@SuppressWarnings("unchecked")
	public List<T> getAll() {
		return createCriteria().list();
	}
	
}
